﻿using AutoMapper;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.EntityFrameworkCore;
using NPOI.HPSF;
using StarsAdmin.Application.Auth.Dtos;
using StarsAdmin.Application.Menu.Dtos;
using StarsAdmin.Application.User.Dtos;
using StarsAdmin.Core.Cache;
using StarsAdmin.Core.Consts;
using StarsAdmin.Core.DB.Entities;
using StarsAdmin.Core.Exceptions;
using StarsAdmin.Core.Extensions;
using StarsAdmin.Core.Helpers;
using StarsAdmin.Core.Models;
using StarsAdmin.Repository.Role;
using StarsAdmin.Repository.User;
using System.IO;
using System.Linq;

namespace StarsAdmin.Application.User.Services
{
    public class UserService : IUserService
    {
        private readonly IMapper _mapper;
        private readonly ICacheService _cache;
        private readonly IUserRepository _userRepository;
        private readonly IRoleRepository _roleRepository;
        private readonly IWebHostEnvironment _webHostEnvironment;

        public UserService(IUserRepository userRepository, IMapper mapper, ICacheService cacheService, IRoleRepository roleRepository, IWebHostEnvironment webHostEnvironment)
        {
            _mapper = mapper;
            _cache = cacheService;
            _userRepository = userRepository;
            _roleRepository = roleRepository;
            _webHostEnvironment = webHostEnvironment;
        }

        #region 查询

        public async Task<List<UserDto>> GetAllAsync(BaseQueryInput input)
        {
            var result = await _userRepository.GetAll()
             .AsNoTracking()
             .WhereIf(input != null && input.QueryConditions.Any(), input.QueryConditions)
             .OrderByIf(input != null && input.Sort != null, input.Sort, input.Order != false)
             .Include(e => e.Roles)
             .ToListAsync();

            return _mapper.Map<List<UserDto>>(result);
        }

        public async Task<Page<UserDto>> GetPageAsync(PageQueryInput input)
        {
            var result = await _userRepository.GetAll().AsNoTracking()
                   .WhereIf(input != null && input.QueryConditions.Any(), input.QueryConditions)
                   .OrderByIf(input != null && input.Sort != null, input.Sort, input.Order != false)
                   .Include(e => e.Roles)
                   .ToPageListAsync(input.CurrentPage, input.PageSize);
            return _mapper.Map<Page<UserDto>>(result);
        }

        public async Task<UserDto?> GetByNameAsync(string userName)
        {
            var result = await _userRepository.GetBy(e => e.UserName == userName).Include(e => e.Roles).FirstOrDefaultAsync();
            return _mapper.Map<UserDto>(result);
        }

        public async Task<UserDto?> GetByEmailAsync(string email)
        {
            var result = await _userRepository.GetBy(e => e.Email == email).Include(e => e.Roles).FirstOrDefaultAsync();
            return _mapper.Map<UserDto>(result);
        }

        public async Task<UserDto?> GetByPhoneNumberAsync(string phoneNumber)
        {
            var result = await _userRepository.GetBy(e => e.PhoneNumber == phoneNumber).Include(e => e.Roles).FirstOrDefaultAsync();
            return _mapper.Map<UserDto>(result);
        }

        public async Task<UserDto?> GetByIdAsync(long id)
        {
            var result = await _userRepository.GetById(id).Include(e => e.Roles).FirstOrDefaultAsync();
            return _mapper.Map<UserDto>(result);
        }

        public async Task<List<UserDto>> GetByIdsAsync(long[] ids)
        {
            var result = await _userRepository.GetByIds(ids).ToListAsync();
            return _mapper.Map<List<UserDto>>(result);
        }

        #endregion 查询

        #region 导入导出

        public async Task<FileContentResult?> ExportTemplateAsync()
        {
            var filePath = "template/用户管理.xlsx";
            var localPath = _webHostEnvironment.WebRootPath.CombineAndFormatPath(filePath);
            // 检查文件是否存在
            if (!System.IO.File.Exists(localPath))
            {
                throw new NotFoundException("未找到指定的模版文件。");
            }
            return await FileExtension.ExportExcelFileAsync(localPath);
        }

        public async Task<FileContentResult?> ExportAsync(long[] ids)
        {
            var export = await _userRepository.GetByIds(ids).ToListAsync();
            return await _mapper.Map<List<ExportUserDto>>(export).ToExcelAsync("用户管理");
        }

        public async Task<bool> ImportAsync(List<AddUserInput> inputs)
        {
            var entities = _mapper.Map<List<UserEntity>>(inputs);
            var roleIds = inputs.SelectMany(e => e.RoleIds ?? []).ToList();
            if (roleIds != null && roleIds.Count != 0)
            {
                var roles = await _roleRepository.GetByIdsAsync(roleIds);
                if (roles == null || !roles.Any())
                {
                    throw new NotFoundException("未找到指定的角色。");
                }
                foreach (var entity in entities)
                {
                    if (entity.RoleIds != null && entity.RoleIds.Length != 0)
                    {
                        entity.Roles = roles.Where(e => entity.RoleIds.Contains(e.Id)).ToList();
                    }
                }
            }
            var result = await _userRepository.AddRangeAndSaveAsync(entities);
            if (result)
            {
                await _cache.RemoveAsync(CacheKeyConst.UserCacheKey);
            }
            return result;
        }

        #endregion 导入导出

        #region 添加

        public async Task<bool> AddAsync(AddUserInput input)
        {
            var entity = _mapper.Map<UserEntity>(input);
            if (input.RoleIds != null && input.RoleIds.Length != 0)
            {
                var roles = await _roleRepository.GetByIdsAsync(input.RoleIds);
                if (roles == null || !roles.Any())
                {
                    throw new NotFoundException("未找到指定的角色。");
                }
                entity.Roles = await roles.ToListAsync();
            }
            var result = await _userRepository.AddAndSaveAsync(entity);
            if (result)
            {
                await _cache.RemoveAsync(CacheKeyConst.UserCacheKey);
            }
            return result;
        }

        #endregion 添加

        #region 更新

        public async Task<bool> UpdateUserInfoAsync(UpdateUserInfoInput input)
        {
            var entity = await _userRepository.GetByIdAsync(input.Id);
            if (entity == null)
            {
                throw new NotFoundException("未找到指定的用户。");
            }
            entity.Name = input.Name ?? "";
            entity.NickName = input.NickName ?? "";
            entity.Description = input.Description ?? "";

            var result = await _userRepository.UpdateAndSaveAsync(entity);
            if (result)
            {
                await _cache.RemoveAsync(CacheKeyConst.UserCacheKey);
            }
            return result;
        }

        public async Task<bool> UpdatePhoneNumberAsync(UpdatePhoneNumberInput input)
        {
            var entity = await _userRepository.GetByIdAsync(input.Id);
            if (entity == null)
            {
                throw new NotFoundException("未找到指定的用户。");
            }
            entity.PhoneNumber = input.PhoneNumber;
            var result = await _userRepository.AttachAndSaveAsync(entity, e => e.PhoneNumber);
            if (result)
            {
                await _cache.RemoveAsync(CacheKeyConst.UserCacheKey);
            }
            return result;
        }

        public async Task<bool> UpdateEmailAsync(UpdateEmailInput input)
        {
            var entity = await _userRepository.GetByIdAsync(input.Id);
            if (entity == null)
            {
                throw new NotFoundException("未找到指定的用户。");
            }
            entity.Email = input.Email;
            var result = await _userRepository.AttachAndSaveAsync(entity, e => e.Email);
            if (result)
            {
                await _cache.RemoveAsync(CacheKeyConst.UserCacheKey);
            }
            return result;
        }

        public async Task<bool> UpdateAvatarAsync(UpdateAvatarInput input)
        {
            var entity = await _userRepository.GetByIdAsync(input.Id);
            if (entity == null)
            {
                throw new NotFoundException("未找到指定的用户。");
            }
            entity.Avatar = input.Avatar;
            var result = await _userRepository.AttachAndSaveAsync(entity, e => e.Avatar);
            if (result)
            {
                await _cache.RemoveAsync(CacheKeyConst.UserCacheKey);
            }
            return result;
        }

        public async Task<bool> UpdatePasswordAsync(UpdatePasswordInput input)
        {
            var entity = await _userRepository.GetByIdAsync(input.Id);
            if (entity == null)
            {
                throw new NotFoundException("未找到指定的用户。");
            }
            // 验证密码
            var pwHash = MD5Helper.MD5Encrypt32(entity.PasswordSalt + input.OldPassword);
            if (pwHash != entity.PasswordHash)
            {
                throw new NotFoundException("密码错误");
            }
            // 修改密码
            entity.PasswordSalt = StringHelper.GenerateRandomString(5);
            entity.PasswordHash = MD5Helper.MD5Encrypt32(entity.PasswordSalt + input.NewPassword);

            var result = await _userRepository.UpdateAndSaveAsync(entity);
            if (result)
            {
                await _cache.RemoveAsync(CacheKeyConst.UserCacheKey);
            }
            return result;
        }

        public async Task<bool> PasswordResetAsync(PasswordResetInput input)
        {
            var result = false;
            if (input.Id != null && input.Id != 0)
            {
                var entity = await _userRepository.GetByIdAsync((long)input.Id);
                if (entity == null)
                {
                    throw new NotFoundException("未找到指定的用户。");
                }
                entity.PasswordSalt = StringHelper.GenerateRandomString(5);
                entity.PasswordHash = MD5Helper.MD5Encrypt32(entity.PasswordSalt + "123456");
                result = await _userRepository.UpdateAndSaveAsync(entity);
            } else if (input.Ids != null && input.Ids.Length != 0)
            {
                var entities = await _userRepository.GetByIdsAsync(input.Ids);

                if (entities == null || entities.Count() == 0)
                {
                    throw new NotFoundException("未找到指定的用户。");
                }
                foreach (var entity in entities)
                {
                    entity.PasswordSalt = StringHelper.GenerateRandomString(5);
                    entity.PasswordHash = MD5Helper.MD5Encrypt32(entity.PasswordSalt + "123456");
                }
                result = await _userRepository.UpdateRangeAndSaveAsync(entities);
            }

            if (result)
            {
                await _cache.RemoveAsync(CacheKeyConst.UserCacheKey);
            }
            return result;
        }

        public async Task<bool> AssignPermissionsAsync(AssignPermissionsInput input)
        {
            var entity = await _userRepository.GetById(input.Id).Include(e => e.Roles).FirstOrDefaultAsync();
            if (entity == null)
            {
                throw new NotFoundException("未找到指定的用户。");
            }
            var roles = await _roleRepository.GetByIdsAsync(input.Ids);
            if (roles == null || !roles.Any())
            {
                throw new NotFoundException("未找到指定的角色。");
            }
            entity.Roles.Clear();
            entity.Roles = await roles.ToListAsync();
            var result = await _userRepository.UpdateAndSaveAsync(entity);
            if (result)
            {
                await _cache.RemoveAsync(CacheKeyConst.UserCacheKey);
            }
            return result;
        }

        public async Task<bool> UpdateAsync(UpdateUserInput input)
        {
            var user = await _userRepository.GetByIdAsync(input.Id);
            if (user == null)
            {
                throw new NotFoundException("未找到指定的用户。");
            }
            var entity = _mapper.Map(input, user);
            if (input.RoleIds != null && input.RoleIds.Length != 0)
            {
                var roles = await _roleRepository.GetByIdsAsync(input.RoleIds);
                if (roles == null || !roles.Any())
                {
                    throw new NotFoundException("未找到指定的角色。");
                }
                entity.Roles.Clear();
                entity.Roles = await roles.ToListAsync();
            }
            var result = await _userRepository.UpdateAndSaveAsync(entity);
            if (result)
            {
                await _cache.RemoveAsync(CacheKeyConst.UserCacheKey);
            }
            return result;
        }

        public async Task<bool> EnabledAsync(long userId)
        {
            var entity = await _userRepository.GetByIdAsync(userId);
            if (entity == null)
            {
                throw new NotFoundException("未找到指定的用户。");
            }
            entity.IsEnabled = !entity.IsEnabled;
            var result = await _userRepository.UpdateAndSaveAsync(entity);
            if (result)
            {
                await _cache.RemoveAsync(CacheKeyConst.UserCacheKey);
            }
            return result;
        }

        #endregion 更新

        #region 删除

        public async Task<bool> DeleteAsync(long id)
        {
            var entity = await _userRepository.GetById(id).Include(e => e.Roles).FirstOrDefaultAsync();
            if (entity == null)
            {
                throw new NotFoundException("未找到指定的用户。");
            }
            var result = await _userRepository.DeleteAsync(entity.Id);
            if (result)
            {
                entity.Roles.Clear();
                await _userRepository.SaveChangesAsync();
                await _cache.RemoveAsync(CacheKeyConst.UserCacheKey);
            }
            return result;
        }

        public async Task<bool> BatchDeleteAsync(long[] ids)
        {
            var entities = await _userRepository.GetByIds(ids).Include(e => e.Roles).ToListAsync();
            if (entities == null || entities.Count < 1)
            {
                throw new NotFoundException("未找到指定的用户。");
            }
            var result = await _userRepository.DeleteRangeAsync(ids);
            if (result)
            {
                foreach (var entity in entities)
                {
                    entity?.Roles.Clear();
                }
                await _userRepository.SaveChangesAsync();
                await _cache.RemoveAsync(CacheKeyConst.UserCacheKey);
            }
            return result;
        }

        #endregion 删除
    }
}